<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        @property --x {
            syntax: "<length>";
            initial-value: 0px;
            inherits: false;
        }

        @property --y {
            syntax: "<length>";
            initial-value: 0px;
            inherits: false;
        }

        @property --x2 {
            syntax: "<length>";
            initial-value: 0px;
            inherits: false;
        }

        @property --r {
            syntax: "<angle>";
            initial-value: 0deg;
            inherits: false;
        }

        @property --x3 {
            syntax: "<length>";
            initial-value: 0px;
            inherits: false;
        }

        @property --r2 {
            syntax: "<angle>";
            initial-value: 0deg;
            inherits: false;
        }

        body {
            margin: 0;
        }

        .wrapper {
            display: flex;
            flex-wrap: wrap;
            position: relative;
        }

        .d {
            position: absolute;
            width: 2px;
            height: 2px;
            border-radius: 50%;
            background-color: red;
        }

        .dot {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background-color: black;
            margin: 100px 150px;
        }

        .dot1 {
            transform: translate(var(--x), var(--y));
            animation: x 1s, y 0.5s;
            animation-timing-function: cubic-bezier(0.5, -300, 0.5, 300);
            animation-iteration-count: infinite;
        }


        /* x 一个来回， y 2个来回 */
        @keyframes x {
            100% {
                --x: 1px;
            }
        }

        @keyframes y {

            100% {
                --y: 0.2px;
            }
        }

        .dot2 {
            transform: rotate(var(--r)) translateX(var(--x2));
            animation: x2 2s, r 8s;
            animation-timing-function: cubic-bezier(0.5, -300, 0.5, 300);
            animation-iteration-count: infinite;
        }

        @keyframes x2 {
            to {
                --x2: 1px;
            }
        }

        @keyframes r {
            to {
                --r: 1deg;
            }
        }

        .dot3 {
            transform: rotate(var(--r2)) translateX(var(--x3));
            /* 图形1 */
            /* animation: x3 2s cubic-bezier(0.5, -300, 0.5, 300), r2 1s linear; */
            /* 图形2 六环 */
            /* animation: x3 2s cubic-bezier(0.5, -300, 0.5, 300), r2 3s linear;  */
            /* 图形3 四环 蝴蝶翅膀形状 */
            animation: x3 2s cubic-bezier(0.5, -300, 0.5, 300), r2 4s linear; 
            /* 图形3 五环花瓣 */
            /* animation: x3 6s cubic-bezier(0.5, -300, 0.5, 300), r2 10s linear;  */
            animation-iteration-count: infinite;
        }

        @keyframes x3 {
            to {
                --x3: 1px;
            }
        }

        @keyframes r2 {
            to {
                --r2: 360deg;
            }
        }
    </style>
</head>

<body>
    <div class="wrapper">
        <div class="dot dot1"></div>
        <div class="dot dot2"></div>
        <div class="dot dot3"></div>
    </div>

    <script>
        const dots = document.querySelectorAll('.dot');
        const wrapper = document.querySelector('.wrapper');

        const track = dom => {
            let i = 0
            let ds = []
            const draw = () => {
                const { x, y, width, height } = dom.getBoundingClientRect();
                const d = document.createElement('div');
                d.className = 'd'
                d.style.left = x + width / 2 + 'px';
                d.style.top = y + height / 2 + 'px';
                wrapper.appendChild(d);
                requestAnimationFrame(draw)
                ds.push(d)
                if (ds.length > 1000) {
                    ds.pop().remove()
                }
            }
            draw()
        }
        Array.from(dots).forEach(track)
    </script>
</body>

</html>